<?php

namespace App;

defined('ROOT_PATH') or exit('constant ROOT_PATH not defined!');

//namespace App;

class Bootstrap
{
    private static $_router;

    public static function createWebApplication(array $options)
    {
        self::_init();
        $request = new Controller\Request();
        //$request = Controller\Request::getInstance();
        $routeMap = array(
            'module'     => 'guestbook',
            'controller' => 'index',
            'action'     => 'default',
        );
        $routeClass = 'App\Controller\Router';
        isset($options['routeClass']) && $routeClass = $options['routeClass'];
        self::$_router = new $routeClass($routeMap, $request);
        self::$_router->match($request->getPathInfo());//
        return new self();
    }

    public static function createCliApplication()
    {

    }

    //firebug->firePHP 主要用于测试
    public static function createConsoleApplication()
    {

    }

    public function run()
    {
        try
        {
            self::$_router->dispatch();
        }
        catch (Exception $e)
        {
            self::exceptionHandler($e);
        }
    }

    //系统初始化
    private static function _init()
    {
        error_reporting(E_ALL | E_STRICT);

        if (version_compare(PHP_VERSION, '5.3.0') < 0)
        {
            exit('PHP Runtime Environmental requirements 5.3+');
        }

        date_default_timezone_set('PRC');//PRC代表中国，等同于 Etc/GMT-8，Asia/Chongqing ，Asia/Shanghai ，Asia/Urumqi

        set_error_handler(function($errno, $errstr, $errfile, $errline){
            throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
        });

        //handler get|post|cookie
        if (get_magic_quotes_gpc())
        {
            function stripslashes_deep($value)
            {
                $value = is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);

                return $value;
            }

            $_GET    = stripslashes_deep($_GET);
            $_POST   = stripslashes_deep($_POST);
            $_COOKIE = stripslashes_deep($_COOKIE);
        }
    }

    private static function exceptionHandler(Exception $exception)
    {

    }


	/**
	 * Returns an array of HTML strings that represent each step in the backtrace.
	 *
	 *     // Displays the entire current backtrace
	 *     echo implode('<br/>', Kohana::trace());
	 *
	 * @param   string  path to debug
	 * @return  string
	 */
	public static function trace(array $trace = NULL)
	{
		if ($trace === NULL)
		{
			// Start a new trace
			$trace = debug_backtrace();
		}

		// Non-standard function calls
		$statements = array('include', 'include_once', 'require', 'require_once');

		$output = array();
		foreach ($trace as $step)
		{
			if ( ! isset($step['function']))
			{
				// Invalid trace step
				continue;
			}

			if (isset($step['file']) AND isset($step['line']))
			{
				// Include the source of this step
				$source = Kohana::debug_source($step['file'], $step['line']);
			}

			if (isset($step['file']))
			{
				$file = $step['file'];

				if (isset($step['line']))
				{
					$line = $step['line'];
				}
			}

			// function()
			$function = $step['function'];

			if (in_array($step['function'], $statements))
			{
				if (empty($step['args']))
				{
					// No arguments
					$args = array();
				}
				else
				{
					// Sanitize the file path
					$args = array($step['args'][0]);
				}
			}
			elseif (isset($step['args']))
			{
				if ( ! function_exists($step['function']) OR strpos($step['function'], '{closure}') !== FALSE)
				{
					// Introspection on closures or language constructs in a stack trace is impossible
					$params = NULL;
				}
				else
				{
					if (isset($step['class']))
					{
						if (method_exists($step['class'], $step['function']))
						{
							$reflection = new ReflectionMethod($step['class'], $step['function']);
						}
						else
						{
							$reflection = new ReflectionMethod($step['class'], '__call');
						}
					}
					else
					{
						$reflection = new ReflectionFunction($step['function']);
					}

					// Get the function parameters
					$params = $reflection->getParameters();
				}

				$args = array();

				foreach ($step['args'] as $i => $arg)
				{
					if (isset($params[$i]))
					{
						// Assign the argument by the parameter name
						$args[$params[$i]->name] = $arg;
					}
					else
					{
						// Assign the argument by number
						$args[$i] = $arg;
					}
				}
			}

			if (isset($step['class']))
			{
				// Class->method() or Class::method()
				$function = $step['class'].$step['type'].$step['function'];
			}

			$output[] = array(
				'function' => $function,
				'args'     => isset($args)   ? $args : NULL,
				'file'     => isset($file)   ? $file : NULL,
				'line'     => isset($line)   ? $line : NULL,
				'source'   => isset($source) ? $source : NULL,
			);

			unset($function, $args, $file, $line, $source);
		}

		return $output;
	}
}
